#include "Subject.h"
#include "Observer.h"
using namespace std;

Subject::~Subject(){}

Subject::Subject():observers(EVENT_NUM){}


void Subject::Attach(Observer *observer, EVENT e){
	if(e <= EVENT_ALL || e > EVENT_NUM)
		return;
	/*if(e == EVENT_ALL){
		vector<set<Observer*>>::iterator it = this->observers.begin();
		for(;it!=observers.end();it++){
			it->insert(observer);
		}
		return;
	}*/
	observers[e].insert(observer);
}

void Subject::Detach(Observer *observer, EVENT e){
	if(e < EVENT_ALL || e > EVENT_NUM)
		return;
	if(e == EVENT_ALL){
		vector<set<Observer*>>::iterator it = this->observers.begin();
		for(;it!=observers.end();it++){			
			set<Observer*> currSet = (*it);
			set<Observer*>::iterator setIt = currSet.find(observer);
			if(setIt != currSet.end())
				currSet.erase(setIt);					
		}
		return;
	}
	set<Observer*> currSet = observers[e];
	set<Observer*>::iterator setIt = currSet.find(observer);
	if(setIt != currSet.end())
			currSet.erase(setIt);	
}



void Subject::Notify(EVENT e){
	if(e < EVENT_ALL || e > EVENT_NUM)
		return;
	if(e != EVENT_ALL){
		set<Observer*> lo = observers.at(e);
		set<Observer*>::const_iterator it;
		for(it = lo.begin(); it!=lo.end(); ++it){
			(*it)->Update(this,e);
		}
		return;
	}
	vector<set<Observer*>>::iterator it = this->observers.begin();
		for(;it!=observers.end();++it){			
			set<Observer*>::iterator lt = it->begin();
			for(;lt != it->end();++lt){	
				(*lt)->Update(this,e);
			}
	}
}